package mysqldb

import (
	"database/sql"
	"fmt"
	"server/conf"
	"strconv"
)

var xdb *mysqldb

func GetConnect() *DB {
	// err := xdb.conn.Ping()
	// if err != nil {
	// 	New()
	// }
	return &DB{xdb, "", []string{}, "", "", "", "", "", ""}
}

func GetNew(db *mysqldb) *DB {
	return &DB{db, "", []string{}, "", "", "", "", "", ""}
}

func New() {
	DB_DRIVE := conf.GET["config"]["DB_DRIVE"]
	DB_MAX_OPEN, _ := strconv.Atoi(conf.GET["config"]["DB_MAX_OPEN"])
	DB_MAX_IDLE, _ := strconv.Atoi(conf.GET["config"]["DB_MAX_IDLE"])
	DB_NAME := conf.GET["config"]["DB_NAME"]
	DB_HOST := conf.GET["config"]["DB_HOST"]
	DB_USER := conf.GET["config"]["DB_USER"]
	DB_PASSWD := conf.GET["config"]["DB_PASSWD"]
	DB_PORT := conf.GET["config"]["DB_PORT"]
	DB_CONN := DB_USER + ":" + DB_PASSWD + "@(" + DB_HOST + ":" + DB_PORT + ")/" + DB_NAME + "?charset=utf8"

	xdb = Create(DB_DRIVE, DB_CONN, DB_MAX_IDLE, DB_MAX_OPEN)
}

func execute(tdb interface{}, sqls string, params ...interface{}) ([]map[string]string, error) {
	var rows *sql.Rows
	var err error
	switch tdb.(type) {
	case *sql.DB:
		rows, err = tdb.(*sql.DB).Query(sqls, params...)
		if err != nil {
			return nil, err
		}
		defer rows.Close()
	case *sql.Tx:
		rows, err = tdb.(*sql.Tx).Query(sqls, params...)
		if err != nil {
			return nil, err
		}
		defer rows.Close()
	default:
		fmt.Println("db type error")
	}
	var resp []map[string]string
	columns, err := rows.Columns()
	r := make([]interface{}, len(columns))
	for i, _ := range r {
		var a string
		r[i] = &a
	}
	if err == nil {
		for rows.Next() {
			err := rows.Scan(r...)
			if err == nil {
				res := make(map[string]string)
				for i, j := range r {
					res[columns[i]] = *(j.(*string))
				}
				resp = append(resp, res)
			}
		}
	}
	return resp, err
}

func update(tdb interface{}, sqls string, params ...interface{}) (int64, error) {
	var res sql.Result
	var err error
	switch tdb.(type) {
	case *sql.DB:
		res, err = tdb.(*sql.DB).Exec(sqls, params...)
		if err != nil {
			return 0, err
		}
	case *sql.Tx:
		res, err = tdb.(*sql.Tx).Exec(sqls, params...)
		if err != nil {
			return 0, err
		}
	default:
		fmt.Println("db type error")
	}
	i, _ := res.RowsAffected()
	return i, err
}

func del(tdb interface{}, sqls string, params ...interface{}) (int64, error) {
	var res sql.Result
	var err error
	switch tdb.(type) {
	case *sql.DB:
		res, err = tdb.(*sql.DB).Exec(sqls, params...)
		if err != nil {
			return 0, err
		}
	case *sql.Tx:
		res, err = tdb.(*sql.Tx).Exec(sqls, params...)
		if err != nil {
			return 0, err
		}
	default:
		fmt.Println("db type error")
	}
	i, _ := res.RowsAffected()
	return i, err
}

func insert(tdb interface{}, sqls string, params ...interface{}) (int64, error) {
	var res sql.Result
	var err error
	switch tdb.(type) {
	case *sql.DB:
		res, err = tdb.(*sql.DB).Exec(sqls, params...)
		if err != nil {
			return 0, err
		}
	case *sql.Tx:
		res, err = tdb.(*sql.Tx).Exec(sqls, params...)
		if err != nil {
			return 0, err
		}
	default:
		fmt.Println("db type error")
	}
	i, _ := res.LastInsertId()
	return i, err
}

func insertmanay(tdb interface{}, table string, m ...map[string]interface{}) (int64, error) {
	var res *sql.Stmt
	var err error

	var columns []string
	cs := ""
	vs := ""
	for i, _ := range m[0] {
		columns = append(columns, i)
		cs += ", " + i
		vs += ", ?"
	}
	update_sql := "INSERT INTO %s (%s) VALUES (%s)"
	update_sql = fmt.Sprintf(update_sql, table, cs[2:], vs[2:])

	switch tdb.(type) {
	case *sql.DB:
		res, err = tdb.(*sql.DB).Prepare(update_sql)
		if err != nil {
			return 0, err
		}
		defer res.Close()
	case *sql.Tx:
		res, err = tdb.(*sql.Tx).Prepare(update_sql)
		if err != nil {
			return 0, err
		}
		defer res.Close()
	default:
		fmt.Println("db type error")
	}
	// var sr sql.Result
	var count int64
	count = 0
	for _, j := range m {
		var values []interface{}
		for _, v := range columns {
			values = append(values, j[v])

		}
		_, err = res.Exec(values...)
		if err != nil {
			return count, err
		}
		count += 1
	}
	return count, err
}

func init() {
	New()
}
